extends MoveElement


class_name MoveController


## 状态结束时是否自动释放子组件
@export var is_release_state_when_completed: bool = false
## 所有移动状态
@export var state: PackedStateResource = null:
    set(v):
        state = v
        if move_component:
            on_move_ready()
## 需要追踪时的目标
@export var target_or_finder: Node = null


var index: int = 0
var current_state: MoveStateResource = null
var current_data: Dictionary = {}
var current_duration: float = 0

var storage: Array[Dictionary] = []
var start_direction: Vector2 = Vector2.ZERO
var start_position: Vector2 = Vector2.ZERO
var start_speed: float = 0
var target: Node2D = null


func __check_exports() -> Dictionary:
    return IComponent.merge({
        "target_or_finder": [IComponent.find_child.bind(self, func(x): return x is INodeFinder, target_or_finder)],
    }, super.__check_exports())

func __prepare() -> void:
    super.__prepare()

    if target_or_finder != null:
        GameService.notify_died.connect(on_enemy_died)

func __reset() -> void:
    if target_or_finder != null:
        GameService.notify_died.disconnect(on_enemy_died)
    super.__reset()

func on_enemy_died(enemy: Node2D) -> void:
    if target == enemy:
        target = find_target()

# MoveComponent就绪时触发
func on_move_ready() -> void:
    if not state or state.elements.size() < 1:
        is_enable = false
        return
    storage.clear()
    for i in range(state.elements.size()):
        storage.append({})
    index = 0
    start_direction = move_component.direction
    start_position = move_component.wrapper.position
    start_speed = move_component.speed
    target = find_target()
    init_state()
    is_enable = true

func find_target() -> Node2D:
    return target_or_finder.find() if target_or_finder else target_or_finder

func init_state() -> void:
    current_state = state.elements[index]
    current_data = storage[index]
    current_duration = 0
    current_state.enter(self, current_data)

# 转向时触发
func on_move_direction_changed() -> void:
    pass

# 迭代加速逻辑,返回附加的速度
func yield_move(delta: float) -> Vector2:
    var is_done: bool = current_state.update(self, current_data, delta, current_duration)
    if is_done:
        current_state.exit(self, current_data)
        if current_state.next_state == 0:
            index += 1
        elif current_state.next_state > 0 and current_state.next_state <= state.elements.size():
            index = current_state.next_state - 1
        else:
            index = state.elements.size()
        if index < state.elements.size():
            init_state()
        else:
            is_enable = false
            if is_release_state_when_completed:
                state = null
            else:
                index = 0
                current_state = state.elements[index]
    else:
        current_duration += delta
    return Vector2.ZERO
